package com.sojson.udp.util;

import java.net.InetSocketAddress;

import com.sojson.config.exception.TransException;
import com.sojson.udp.util.bean.UdpConnect;
import com.sojson.udp.util.enums.EUdpControl;
import com.sojson.udp.util.enums.EUdpControlValue;
import com.sojson.util.HexUtil;
import com.sojson.util.encrypt.bothway.alike.aes.AesUtil;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * Udp工具类
 * 
 * @author liu
 * @date 2024-05-31
 */
@Data
@Slf4j
public class UdpUtil {

    /** 头 */
    public static final String HEAD = "68";
    /** 结尾 */
    public static final String END = "16";
    /** 版本 */
    public static final String VERSION = "01";
    /** 秘钥 */
    public static String key = "XXXXXXWATERGROUP";
    /** 厂商 */
    public static String firm = "0000";

    /**
     * 获取报文
     * 
     * @param control
     * @param tokenId
     * @param status
     * @param data
     * @return
     * @throws Exception 
     */
    private static String getMessage(EUdpControl control, String tokenId, String status, String data)
        throws Exception {
        data = AesUtil.encryptToHex(data, UdpUtil.key);
        String num = HexUtil.toHex(data.length() / 2, 2);

        StringBuilder str = new StringBuilder(HEAD);
        str.append(firm);
        str.append(HexUtil.reverse(tokenId));
        str.append(VERSION);
        str.append(status);
        str.append(control.getCode());
        str.append(HexUtil.reverse(num));
        str.append(data);
        str.append(HexUtil.sumHexAndModule(str.toString()));
        str.append(END);
        return str.toString();
    }

    /**
     * 发送报文
     * 
     * @param control
     * @param tokenId
     * @param status
     * @param data
     * @return
     * @throws Exception 
     */
    private static void sendMessage(EUdpControl control, String tokenId, String status, String data)
        throws Exception {
        String msg = getMessage(control, tokenId, status, data);

        sendInfo(tokenId, msg);
    }

    /**
     * 发送消息
     * 
     * @param tokenId
     * @param msg
     */
    private static void sendInfo(String tokenId, String msg) {
        UdpConnect connect = UdpPoolUtil.get(tokenId);
        if (connect == null) {
            throw new TransException("此设备未注册");
        }
        byte[] responseData = HexUtil.parseHex(msg);
        ChannelHandlerContext context = connect.getCtx();
        DatagramPacket packet = connect.getPacket();
        String ip = packet.sender().getAddress().getHostAddress();
        int port = packet.sender().getPort();

        InetSocketAddress address = new InetSocketAddress(ip, port);
        DatagramPacket responsePacket = new DatagramPacket(Unpooled.copiedBuffer(responseData), address);
        context.writeAndFlush(responsePacket);

        log.info(new StringBuilder("Udp发送到: ").append(tokenId).append("消息,").append(msg).toString());
    }

    /**
     * 控阀
     * 
     * @param tokenId
     * @param controlValue
     * @return
     * @throws Exception 
     */
    public static void controlValue(String tokenId, EUdpControlValue controlValue) throws Exception {
        sendMessage(EUdpControl.CONTROL_VALUE, tokenId, "C00000", "70020000" + controlValue.getCode());
    }

}